package com.weasel.http.builder;

import com.weasel.http.adapter.ResponseAdapter;
import com.weasel.http.adapter.SimpleResponseAdapter;
import com.weasel.http.helper.HttpResponseHelper;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

/**
 * Created by Dylan on 2015/10/8.
 */
public abstract class AbstractHttpMethodBuilder<M extends AbstractHttpMethodBuilder> {

    protected final static CloseableHttpClient httpClient = HttpClients.createDefault();

    public M withURI(String uri){

        try {
            getMethod().setURI(new URI(uri));
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        return (M)this;
    }

    public M addHeader(String name,String value){

        getMethod().addHeader(name,value);
        return (M)this;
    }

    public CloseableHttpResponse doIt(){

        try {
            CloseableHttpResponse response = httpClient.execute(getMethod());
            return response;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public <T> T doIt(ResponseHandler<T> responseHandler) throws IOException {

        return httpClient.execute(getMethod(),responseHandler);
    }


    public <T> T doItWithJson(final Class<T> clazz) throws IOException {

        return doItWithJson(clazz, new SimpleResponseAdapter());

    }

    public <T> T doItWithJson(final Class<T> clazz,ResponseAdapter adapter) throws IOException {

        return httpClient.execute(getMethod(), new ResponseHandler<T>() {

            @Override
            public T handleResponse(HttpResponse response)
                    throws ClientProtocolException, IOException {

                return HttpResponseHelper.jsonResponseToEntity(response, clazz, adapter);
            }
        });

    }


    public <T> T doItWithXml(final Class<T> clazz) throws IOException {

        return doItWithXml(clazz,new SimpleResponseAdapter());

    }

    public <T> T doItWithXml(final Class<T> clazz,final ResponseAdapter adapter) throws IOException {

        return httpClient.execute(getMethod(), new ResponseHandler<T>() {

            @Override
            public T handleResponse(HttpResponse response)
                    throws ClientProtocolException, IOException {

                return HttpResponseHelper.xmlResponseToEntity(response,clazz,adapter);
            }
        });

    }


    protected abstract HttpRequestBase getMethod();
}
